﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;

using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;

namespace Client
{
    public partial class FormClient : Form
    {
        //define opCode;
        const int PAUSE = -1;
        const int LOGIN = 0;
        const int REG = 1;
        const int EXIT = 2;
        const int LOGINSUCCESSFULL = 3;
        const int UPDATECLIENTLIST = 4;
        const int SHARE = 5;
        const int SEARCH = 6;
        const int DOWNLOAD = 7;
        const int LOGOUT = 8;
        const int LOGINFAIL = 9;
        const int REQUEST_DOWNLOAD = 10;
        const int TRACK_AVAILABLE = 11;
        const int TRACK_NOTAVAILABLE = 12;
        const int READY_DOWNLOAD = 13;
        const int REG_SUCCESSFUL = 14;
        const int REG_FAILURE = 15;
        

        private FormConnect formConnect = new FormConnect();
        private FormLogin formLogin;
        private FormREG formReg;


        private TcpClient tcpClient;
        private static int port = 1234;

        List<string> IPDownLoadList = new List<string>();

        private bool flagConnected = false;
        private Thread myThread = null;
        private bool threadStop = false;
        private bool PauseDownload = false;

        private string fileDownloading;

        public FormClient()
        {
            InitializeComponent();
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            formConnect.ShowDialog();
            flagConnected = formConnect.getConnectionStatus();
            if (flagConnected)
            {
                tcpClient = formConnect.getTcpClient();
                string IP = formConnect.getServerIP();
                myThread = new Thread(new ThreadStart(receive));
                myThread.Start();
                loginToolStripMenuItem.Enabled = true;
                regToolStripMenuItem.Enabled = true;
                connectToolStripMenuItem.Enabled = false;
            }
        }

        private delegate void updateGuiHandle();
        private void updateGui_Login()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new updateGuiHandle(updateGui_Login), new object[] { });
                return;
            }
            formLogin.Close();
            tabControl.Enabled = true;
            loginToolStripMenuItem.Enabled = false;
            regToolStripMenuItem.Enabled = false;
            logOutToolStripMenuItem.Enabled = true;
        }

        private delegate void updateGuiRegHandle();
        private void updateGui_Reg()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new updateGuiHandle(updateGui_Reg), new object[] { });
                return;
            }
            formReg.Close();
            tabControl.Enabled = false;
            loginToolStripMenuItem.Enabled = true;
            regToolStripMenuItem.Enabled = false;
            logOutToolStripMenuItem.Enabled = false;
        }


        private void loginToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //if (myThread != null)
            //{
            //    myThread.Abort();
            //}
            formLogin = new FormLogin(tcpClient);
            formLogin.ShowDialog();

            if (formLogin.getLoginStatus())
            {
                this.flagConnected = true;

                regToolStripMenuItem.Enabled = false;
                loginToolStripMenuItem.Enabled = false;
                logOutToolStripMenuItem.Enabled = true;
                tabControl.Enabled = true;
            }
        }
        //public delegate void AddListItem();
        //public AddListItem myDelegate;
        private delegate void updateProgressBarHandle(float value);
        //private updateProgressBarHandle 
        //    //new AddListItem(AddListItemMethod);
        private void updateProgressBar(float value)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new updateProgressBarHandle(updateProgressBar), new object[] {value });
                return;
            }
            progressBarDownloading.Value =(int) value;
        }
        private static Mutex mut = new Mutex();
        private static Mutex mut1 = new Mutex();
        private void upLoad(object para)
        {
            object[] objectPara = (object[])para;
            int startOfFile = (int)objectPara[0];
            int currentPort = (int)objectPara[1];
            //MessageBox.Show("Port upload = " + currentPort.ToString());
            string location = (string)objectPara[2];
            
            FileStream inStream = new FileStream(location, FileMode.Open, FileAccess.Read);
            try
            {
                TcpListener listener = new TcpListener(currentPort);
                listener.Start();
                TcpClient client = listener.AcceptTcpClient();
                NetworkStream ns = client.GetStream();
                //////////////////////////
               // Thread.Sleep(2000);
                /////////////////////////////
                long n = (inStream.Length - startOfFile) / 1024;
                long currentTotal = startOfFile;
                byte[] buffer = new byte[1024];
                ns.Write(BitConverter.GetBytes(inStream.Length), 0, 4);//send length of file
                inStream.Seek(startOfFile, SeekOrigin.Begin);//
               
                for (long i = 0; i < n; i++)
                {
                    currentTotal += inStream.Read(buffer, 0, 1024);
                    ns.Write(buffer, 0, 1024);
                  //  mut.WaitOne();
                   // Thread.Sleep(100);
                    if (ns.CanRead)
                    {
                        ns.Read(buffer, 0, 4);
                    }
                  //  mut.ReleaseMutex();
                    //mut.WaitOne();
                    if(BitConverter.ToInt32(buffer, 0) == PAUSE)
                    {
                        inStream.Close();
                        ns.Write(BitConverter.GetBytes(1), 0, 4);
                        Thread.Sleep(1000);
                        ns.Close();
                       // mut.ReleaseMutex();
                        return;
                    }
                    //mut.ReleaseMutex();
                }
                mut.WaitOne();
                if (PauseDownload)
                {
                   // mut.WaitOne();
                    inStream.Close();
                    ns.Write(BitConverter.GetBytes(1), 0, 4);
                    //ns.Close();
                    mut.ReleaseMutex();
                    
                    return;
                }
                mut.ReleaseMutex();
                if (currentTotal < inStream.Length)
                {
                    buffer = new byte[1024];
                    int lastBlockSize = (int)(inStream.Length - currentTotal);
                    buffer = new byte[lastBlockSize];
                    inStream.Read(buffer, 0, buffer.Length);
                    ns.Write(BitConverter.GetBytes(buffer.Length), 0, 4);//send last block size
                    ns.Write(buffer, 0, lastBlockSize);
                }
            }
            catch (System.Exception ex)
            {
                inStream.Close();
               // MessageBox.Show(currentPort.ToString()+ex.ToString());
            }
            inStream.Close();   
        }

        private void pauseDownload()
        {
            PauseDownload = true;
        }
         //private delegate void updateProgressBarHandle(int value);
        private delegate void updateListDownloadingHandle(ListView lv, string pathFile);
        private void updateListDownloading(ListView lv, string pathFile)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new updateListDownloadingHandle(updateListDownloading), new object[] { lv, pathFile });
                return;
            }
            foreach (ListViewItem item in lv.Items)
            {
                if (item.Text==pathFile)
                {
                    lv.Items.Remove(item);
                } 
            }
            
        }
        private delegate void updateStatusOfListDownloadingHandle(ListView lv, string pathFile, float percent);
        private void updateStatusOfListDownloading(ListView lv, string pathFile, float percent)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new updateStatusOfListDownloadingHandle(updateStatusOfListDownloading), new object[] { lv, pathFile, percent });
                return;
            }
            foreach (ListViewItem item in lv.Items)
            {
                if (item.Text == pathFile)
                {
                    item.SubItems[2].Text = percent.ToString();
                }
            }
        }
        private void downLoad(object para)
        {
           // mutexDownload.WaitOne();
            object[] objectPara = (object[])para;
            int currentPort = (int)objectPara[0];
           // MessageBox.Show("port download = " + currentPort.ToString());
            string IP = (string)objectPara[1];
            TcpClient client = new TcpClient();
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(IP), currentPort);
            int tem = 0;
            while (true)
            {
                try
                {
                    client.Connect(ipe);
                    break;
                }
                catch (Exception ex)
                {
                    tem++;
                    //MessageBox.Show(ex.ToString());
                    //return;
                }
            } 
            fileDownloading = pathFile + ".downloading";
            //if (File.Exists(fileDownloading))
            //{
            //    File.Delete(fileDownloading);
            //}
            FileStream outStream = new FileStream(fileDownloading, FileMode.OpenOrCreate, FileAccess.Write);
            try
            {
                byte[] numberBuffer = new byte[4];
                NetworkStream ns = client.GetStream();
                ns.Read(numberBuffer, 0, 4);//read file length
                long fileLen = BitConverter.ToInt32(numberBuffer, 0);
                long n = (fileLen - outStream.Length) / 1024;
                byte[] buffer = new byte[1024];
                long currentTotal = 0;
                float percent;
                int current;
                currentTotal = outStream.Seek(0, SeekOrigin.End);
               // Mutex mut = new Mutex();
                
                for (long i = 0; i < n; i++)
                {
                    current = 0;
                  //  mut.WaitOne();
                    while (current < 1024)
                    {
                        current += ns.Read(buffer, 0, 1024);
                    }
                    ns.Write(BitConverter.GetBytes(999), 0, 4);
                  //  mut.ReleaseMutex();
                   
                    outStream.Write(buffer, 0, 1024);
                    currentTotal += current;
                    percent = (float)(100.0 * currentTotal / fileLen);
                    updateStatusOfListDownloading(listViewDownloadedFile, pathFile, percent);
                    updateProgressBar(percent);
                    mut.WaitOne();
                    if (PauseDownload && percent != 100)
                    {
                        outStream.Close();
                        ns.Write(BitConverter.GetBytes(PAUSE), 0, 4);
                        ns.Read(numberBuffer, 0, 4);
                        // ns.Close();
                        PauseDownload = false;
                        Thread.Sleep(1000);
                        updateStatusOfListDownloading(listViewDownloadedFile, pathFile, percent);
                        updateProgressBar(0);
                        mut.ReleaseMutex();
                        return;
                    }
                    mut.ReleaseMutex();

                }
              
                if (currentTotal < fileLen)
                {
                    ns.Read(numberBuffer, 0, 4);
                    int len = BitConverter.ToInt32(numberBuffer, 0);
                    buffer = new byte[len];
                    ns.Read(buffer, 0, len);
                    outStream.Write(buffer, 0, buffer.Length);
                    updateStatusOfListDownloading(listViewDownloadedFile, pathFile, 100);
                    updateProgressBar(100);
                }
                Thread.Sleep(1000);
                updateStatusOfListDownloading(listViewDownloadedFile, pathFile, 100);
                updateProgressBar(0);
            
            }catch(Exception ex)
            {
               // MessageBox.Show(currentPort.ToString()+ex.ToString());
                outStream.Close();
                return;
            }
            
            outStream.Close();
            //rename
            if (File.Exists(pathFile))
            {
                File.Delete(pathFile);
            }
            else
            {
                File.Move(fileDownloading, pathFile);
            }
            updateListDownloading(listViewDownloadedFile, pathFile);
            MessageBox.Show("Finish!\rFile đã download:\r" + pathFile, "Notify", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        public void receive()
        {
            byte[] opCodeBuffer = new byte[4];
            NetworkStream ns = tcpClient.GetStream();

            while (ns.Read(opCodeBuffer, 0, 4) != 0 && !threadStop)
            {
                int opCode = BitConverter.ToInt32(opCodeBuffer, 0);
                switch (opCode)
                {
                    case REG_FAILURE:
                        {
                            MessageBox.Show("Reg failure! User exits!", "Error");
                        }
                        break;
                    case REG_SUCCESSFUL:
                        {
                            MessageBox.Show("Reg succesful!", "Congratulation");
                            updateGui_Reg();
                        }
                        break;
                    case READY_DOWNLOAD:
                        {
                            byte[] numberBuffer = new byte[4];
                            ns.Read(numberBuffer, 0, 4);//read port of B
                            int portB = BitConverter.ToInt32(numberBuffer, 0);
                            ns.Read(numberBuffer, 0, 4);//read lenght of IP's B
                            int len = BitConverter.ToInt32(numberBuffer, 0);
                            byte[] buffer = new byte[len];
                            ns.Read(buffer, 0, buffer.Length);//read IP's B
                            string IP_B = Encoding.ASCII.GetString(buffer);
                            Thread t = new Thread(new ParameterizedThreadStart(downLoad));
                            object[] para = new object[] { portB, IP_B };
                            t.Start(para);
                        }
                        break;
                    case REQUEST_DOWNLOAD:
                        {
                            byte[] numberBuffer = new byte[4];
                            ns.Read(numberBuffer, 0, 4);//read start of file
                            int startOfSize = BitConverter.ToInt32(numberBuffer, 0);
                            ns.Read(numberBuffer, 0, 4);//read length of location
                            int len = BitConverter.ToInt32(numberBuffer,0);
                            byte[] Buffer = new byte[len];
                            ns.Read(Buffer, 0, len);//read location music
                            string location = Encoding.ASCII.GetString(Buffer);
                            ns.Read(numberBuffer, 0, 4);//read length name of A;
                            len = BitConverter.ToInt32(numberBuffer, 0);
                            Buffer = new byte[len];
                            ns.Read(Buffer, 0, len);//read name of A
                            string AName = Encoding.ASCII.GetString(Buffer);
                            if (File.Exists(location))
                            {
                                ns.Write(BitConverter.GetBytes(TRACK_AVAILABLE), 0, 4);

                                Thread t = new Thread(new ParameterizedThreadStart(upLoad));
                                port+=10;
                                ns.Write(BitConverter.GetBytes(port), 0, 4);//send port
                                ns.Write(BitConverter.GetBytes(AName.Length), 0, 4);//write length of name of A
                                ns.Write(Encoding.ASCII.GetBytes(AName), 0, AName.Length);//write name of A
                                object[] para = new object[] { startOfSize, port, location };
                                t.Start(para);
                            }
                            else
                            {
                                ns.Write(BitConverter.GetBytes(TRACK_NOTAVAILABLE), 0, 4);
                            }
                            
                        }
                        break;
                    case LOGINFAIL:
                        {
                            MessageBox.Show("Error!\rLogin is not successful!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        break;
                    case LOGINSUCCESSFULL:
                        {
                            MessageBox.Show("Login is successful!", "Notify", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            updateGui_Login();
                            //tabControl.Enabled = true;
                            
                        }
                        break;
                    case SEARCH:
                        {
                            ////////////////////////////receive result//////////////////////////////////
                            //listViewResult.Items.Clear();
                            doRemoveItemFromListView(listViewResult);
                            byte[] numberBuffer = new byte[4];
                            ns.Read(numberBuffer, 0, 4);//read number of client have that track
                            int n = BitConverter.ToInt32(numberBuffer, 0);
                            for (int i = 0; i < n; i++)
                            {
                                ns.Read(numberBuffer, 0, 4);//read number of track that client have
                                int count = BitConverter.ToInt32(numberBuffer, 0);
                                for (int j = 0; j < count; j++ )
                                {
                                    ns.Read(numberBuffer, 0, 4);//read length of client name
                                    int len = BitConverter.ToInt32(numberBuffer, 0);
                                    byte[] buffer = new byte[len];
                                    ns.Read(buffer, 0, len);//read client name
                                    string title = Encoding.ASCII.GetString(buffer);

                                    ns.Read(numberBuffer, 0, 4);//read length of client name
                                    len = BitConverter.ToInt32(numberBuffer, 0);
                                    buffer = new byte[len];
                                    ns.Read(buffer, 0, len);//read client name
                                    string name = Encoding.ASCII.GetString(buffer);

                                    ns.Read(numberBuffer, 0, 4);//read length of IP
                                    len = BitConverter.ToInt32(numberBuffer, 0);
                                    buffer = new byte[len];
                                    ns.Read(buffer, 0, len);//read IP
                                    string IP = Encoding.ASCII.GetString(buffer);

                                    //add to listview
                                    ListViewItem lvItem = new ListViewItem(title);
                                    lvItem.SubItems.Add(name);
                                    lvItem.SubItems.Add(IP);
                                    doAddItemToListView(listViewResult, lvItem);
                                }
                            }
                        }
                        break;
                    case UPDATECLIENTLIST:
                        {
                            //for(int i=0; i<listViewClientList.Items.Count; i++)
                            {
                                doRemoveItemFromListView(listViewClientList);
                            }
                            byte[] lenBuffer = new byte[4];
                            byte[] buffer;
                            ns.Read(lenBuffer, 0, 4);//read number of clients
                            int n = BitConverter.ToInt32(lenBuffer, 0);
                            for (int i = 0; i < n; i++)
                            {
                                ns.Read(lenBuffer, 0, 4);//read length of client name i
                                int len = BitConverter.ToInt32(lenBuffer, 0);
                                buffer = new byte[len];
                                ns.Read(buffer, 0, len);//read username
                                string userName = Encoding.ASCII.GetString(buffer, 0, len);

                                ns.Read(lenBuffer, 0, 4);//read length of client IP i
                                len = BitConverter.ToInt32(lenBuffer, 0);
                                buffer = new byte[len];
                                ns.Read(buffer, 0, len);//read IP
                                string IP = Encoding.ASCII.GetString(buffer, 0, len);

                                ListViewItem item = new ListViewItem(IP);
                                item.SubItems.Add(userName);
                                //listViewClientList.Items.Add(item);
                                doAddItemToListView(listViewClientList, item);
                            }
                        }
                        break;
                    default:

                        break;
                }
            }
        }

        private delegate void addItemToListViewDelegate(ListView lv, ListViewItem item);
        private delegate void removeAllItemFromListViewDelegate(ListView lv);
        public void doAddItemToListView(ListView lv, ListViewItem item)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new addItemToListViewDelegate(doAddItemToListView),
                            new object[] { lv, item });
                return;
            }
            lv.Items.Add(item);

        }
        public void doRemoveItemFromListView(ListView lv)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new removeAllItemFromListViewDelegate(doRemoveItemFromListView), new object[] { lv });
                return;
            }
            lv.Items.Clear();

        }
        private void regToolStripMenuItem_Click(object sender, EventArgs e)
        {
            formReg = new FormREG(tcpClient);
            formReg.ShowDialog();

        }

        private void FormClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (flagConnected)
            {
                LogOut();
                threadStop = true;
                NetworkStream ns = tcpClient.GetStream();
                ns.Write(BitConverter.GetBytes(EXIT), 0, 4);
                Environment.Exit(0);
            }
        }



        private void FormClient_Load(object sender, EventArgs e)
        {
            comboBoxSearchType.SelectedIndex = 0;

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (flagConnected)
            {
                threadStop = true;
                NetworkStream ns = tcpClient.GetStream();
                ns.Write(BitConverter.GetBytes(EXIT), 0, 4);

            }
            this.Close();
            Environment.Exit(0);
        }

        private void logOutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LogOut();
            //myThread.Abort();
            //myThread = null;
        }
        private void LogOut()
        {
            loginToolStripMenuItem.Enabled = true;
            regToolStripMenuItem.Enabled = true;
            logOutToolStripMenuItem.Enabled = false;
            NetworkStream ns = tcpClient.GetStream();
            ns.Write(BitConverter.GetBytes(LOGOUT), 0, 4);//send opcode
            tabControl.Enabled = false;
            listViewClientList.Items.Clear();
        }

        private void buttonSearch_Click(object sender, EventArgs e)
        {
            if (textBoxSearch.Text != "")
            {
                NetworkStream ns = tcpClient.GetStream();
                ns.Write(BitConverter.GetBytes(SEARCH), 0, 4);//send opcode

                ns.Write(BitConverter.GetBytes(textBoxSearch.Text.Length), 0, 4);//send length of search string
                ns.Write(Encoding.ASCII.GetBytes(textBoxSearch.Text), 0, textBoxSearch.Text.Length);//send search string

                int searchType = comboBoxSearchType.SelectedIndex;
                ns.Write(BitConverter.GetBytes(searchType), 0, 4);//send search type;
            }
            else
            {
                MessageBox.Show("Warning!\rVui lòng nhập chuỗi để search!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = true;
            dlg.Title = "Choose file music";
            dlg.Filter = "*.mp3|*.mp3";
           
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                foreach (String file in dlg.FileNames)
                {
                    ListViewItem lvItem = new ListViewItem(file);
                    listViewFileAdded.Items.Add(lvItem);
                }
               
            }
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            while(listViewFilesToShare.SelectedItems.Count>0)
            {
                ListViewItem item = listViewFilesToShare.SelectedItems[0];
                    listViewFilesToShare.Items.Remove(item);
            }
        }
        int nFileBeShared;
        private void buttonShare_Click(object sender, EventArgs e)
        {
            NetworkStream ns = tcpClient.GetStream();
            ns.Write(BitConverter.GetBytes(SHARE), 0, 4);//send opcode
            ns.Write(BitConverter.GetBytes(listViewFilesToShare.Items.Count), 0, 4);//send number of files to share

            try
            {
                if (listViewFilesToShare.Items.Count > 0)
                {
                    foreach (ListViewItem item in listViewFilesToShare.Items)
                    {
                        TagLib.File fileTag = TagLib.File.Create(item.Text);
                        nFileBeShared++;
                        string title = " ";
                        if(fileTag.Tag.Title != null)
                        {
                            title = fileTag.Tag.Title;
                        }
                        string album = " ";
                        if (fileTag.Tag.Album != null)
                        {
                            album = fileTag.Tag.Album;
                        }
                        string composer = " ";
                        if (fileTag.Tag.Composers.Length > 0)
                        {
                            composer = fileTag.Tag.Composers[0];
                        }
                        string artist = " ";
                        if (fileTag.Tag.Artists.Length > 0)
                        {
                            artist = fileTag.Tag.Artists[0];
                        }

                        //send title
                        ns.Write(BitConverter.GetBytes(title.Length), 0, 4);//send length of title
                        ns.Write(Encoding.ASCII.GetBytes(title), 0, title.Length);//send title
                        //send album name
                        ns.Write(BitConverter.GetBytes(album.Length), 0, 4);//send length of title
                        ns.Write(Encoding.ASCII.GetBytes(album), 0, album.Length);//send album
                        //send composer
                        ns.Write(BitConverter.GetBytes(composer.Length), 0, 4);//send length of composer
                        ns.Write(Encoding.ASCII.GetBytes(composer), 0, composer.Length);//send composer
                        //send artist
                        ns.Write(BitConverter.GetBytes(artist.Length), 0, 4);//send length of artist
                        ns.Write(Encoding.ASCII.GetBytes(artist), 0, artist.Length);//send artist
                        //send location
                        ns.Write(BitConverter.GetBytes(item.Text.Length), 0, 4);//send length of location
                        ns.Write(Encoding.ASCII.GetBytes(item.Text), 0, item.Text.Length);//send location
                        listViewFilesToShare.Items.Remove(item);
                    }
                    MessageBox.Show("Share file is successful!\rHave "+nFileBeShared.ToString()+" file ", "Notify", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error!\r" + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private static string pathFile = "";
       // private static int mutexDownload = 1;
        private void buttonDownload_Click(object sender, EventArgs e)
        {
            pathFile = "";
            buttonResume.Enabled = false;
            buttonPause.Enabled = true;
            if (listViewResult.SelectedItems.Count > 0)
            {
                FolderBrowserDialog dlg = new FolderBrowserDialog();
                string strFolder = "";
                if (dlg.ShowDialog()==DialogResult.OK)
                {
                    strFolder = dlg.SelectedPath;
                }
                while (listViewResult.SelectedItems.Count > 0)
                {
                    ListViewItem item = listViewResult.SelectedItems[0];

                    pathFile += strFolder + "\\" + item.SubItems[0].Text + ".mp3";
                    if (File.Exists(pathFile))
                    {
                        File.Delete(pathFile);
                    }
                    ListViewItem lvItem = new ListViewItem(pathFile);
                    lvItem.SubItems.Add(item.SubItems[1]);
                    lvItem.SubItems.Add("0");
                    NetworkStream ns = tcpClient.GetStream();
                    ns.Write(BitConverter.GetBytes(REQUEST_DOWNLOAD), 0, 4);//send opcode
                    ns.Write(BitConverter.GetBytes(0), 0, 4);//send start of file
                    ns.Write(BitConverter.GetBytes(item.SubItems[1].Text.Length), 0, 4);//send length of client name B
                    ns.Write(Encoding.ASCII.GetBytes(item.SubItems[1].Text), 0, item.SubItems[1].Text.Length);//send name of client B
                    ns.Write(BitConverter.GetBytes(item.SubItems[0].Text.Length), 0, 4);//send length of track name
                    ns.Write(Encoding.ASCII.GetBytes(item.SubItems[0].Text), 0, item.SubItems[0].Text.Length);//send track name
                    listViewResult.Items.Remove(item);
                    listViewDownloadedFile.Items.Add(lvItem);    
                   
                }
            }
            else
            {
                MessageBox.Show("Chưa chọn file download");
            }

        }

        private void buttonAddToShare_Click(object sender, EventArgs e)
        {
            if (listViewFileAdded.SelectedItems.Count > 0)
            {
                while (listViewFileAdded.SelectedItems.Count > 0)
                {
                    ListViewItem item = listViewFileAdded.SelectedItems[0];
                    listViewFileAdded.Items.Remove(item);
                    listViewFilesToShare.Items.Add(item);
                }
            }
            else
            {
                foreach (ListViewItem item in listViewFileAdded.Items)
                {
                    listViewFileAdded.Items.Remove(item);
                    listViewFilesToShare.Items.Add(item);
                }
            }
            

        }

        private void buttonReturn_Click(object sender, EventArgs e)
        {
            while ( listViewFilesToShare.SelectedItems.Count>0)
            {
                ListViewItem item = listViewFilesToShare.SelectedItems[0];
                listViewFilesToShare.Items.Remove(item);
                listViewFileAdded.Items.Add(item);
            }
        }


        private void buttonPause_Click(object sender, EventArgs e)
        {
            mut.WaitOne();
            pauseDownload();
            buttonResume.Enabled = true;
            buttonPause.Enabled = false;
            buttonDownload.Enabled = true;
            mut.ReleaseMutex();
        }

        private void buttonResume_Click(object sender, EventArgs e)
        {
            pathFile = "";
            buttonDownload.Enabled = false;
            buttonPause.Enabled = true;
            buttonResume.Enabled = false;
            if (listViewDownloadedFile.SelectedItems.Count > 0)
            {
                ListViewItem item = listViewDownloadedFile.SelectedItems[0];
                string downloadFrom = item.SubItems[1].Text;
                pathFile = item.Text;
                //IPDownLoadList.Add(item.SubItems[2].Text);
                if (!File.Exists(pathFile + ".downloading"))
                {
                    updateListDownloading(listViewDownloadedFile, pathFile);
                    updateStatusOfListDownloading(listViewDownloadedFile,pathFile,100);
                    updateProgressBar(100);
                    return;
                }
                FileStream file = new FileStream(pathFile + ".downloading", FileMode.Open, FileAccess.Read);
                int startOfFile = (int)file.Length;
                file.Close();
                string title = getTrackName(pathFile);

                NetworkStream ns = tcpClient.GetStream();
                ns.Write(BitConverter.GetBytes(REQUEST_DOWNLOAD), 0, 4);//send opcode
                ns.Write(BitConverter.GetBytes(startOfFile), 0, 4);//send start of file
                ns.Write(BitConverter.GetBytes(downloadFrom.Length), 0, 4);//send length of client name B
                ns.Write(Encoding.ASCII.GetBytes(downloadFrom), 0, downloadFrom.Length);//send name of client B
                ns.Write(BitConverter.GetBytes(title.Length), 0, 4);//send length of track name
                ns.Write(Encoding.ASCII.GetBytes(title), 0, title.Length);//send track name
            }
            else
            {
                MessageBox.Show("Chưa chọn file để resume", "Error");
            }
        }

        private string getTrackName(string path)
        {
            char[] a = new char[1];
            a[0] = '\\';
            string[] temp = path.Split(a);
            a[0] = '.';
            temp = temp[temp.Length - 1].Split(a);
            return temp[0];
        }

        private void listViewDownloadedFile_SelectedIndexChanged(object sender, EventArgs e)
        {
            PauseDownload = false;
            buttonResume.Enabled = true;
            buttonDownload.Enabled = false;
            buttonPause.Enabled = false;
        }

        private void listViewResult_SelectedIndexChanged(object sender, EventArgs e)
        {
            PauseDownload = false;
            buttonDownload.Enabled = true;
            buttonPause.Enabled = true;
            buttonResume.Enabled = false;
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Show();
            WindowState = FormWindowState.Normal;
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void FormClient_MinimumSizeChanged(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void FormClient_Resize(object sender, EventArgs e)
        {
            if (FormWindowState.Minimized == WindowState)
            {
                this.Hide();
            }
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            WindowState = FormWindowState.Normal;
        }

      

    }
}
